//
//  ZHJNetWorkHelper.m
//  NetWorking
//
//  Created by 红军张 on 2018/7/11.
//  Copyright © 2018年 红军张. All rights reserved.
//

#import "ZHJNetWorkHelper.h"
#import "MBManager.h"
#import "ZHJNetCacheManger.h"
#import "ZHJSecurityPolicy.h"

#define SERVERURL @"https://auth.zjdex.com/authPlatform"
//#define SERVERURL @"https://auth.zjdex.com/test"
NSString * const ZHJNetworkingOperationFailingURLResponseDataErrorKey = @"com.alamofire.serialization.response.error.data";
NSString * const NetworkingOperationFailingURLResponseDataErrorKey = @"com.alamofire.serialization.response.error.data";

@interface ZHJNetWorkHelper()<NSURLSessionDelegate, NSURLSessionTaskDelegate>

@property (strong,nonatomic) NSMutableArray *sessionTaskArr;
/**
 是否需要 缓存
 */
@property (assign,nonatomic) BOOL isCache;

/**
 证书验证对象
 */
@property (strong,nonatomic) ZHJSecurityPolicy *securityPolicy;

@end

@implementation ZHJNetWorkHelper

static ZHJNetWorkHelper *networkManager = nil;

static NSURLSession *_sessionManager;

static NSMutableURLRequest *_requestManager;

#pragma mark 创建单利
+(instancetype _Nonnull)defaultManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!networkManager) {
            networkManager = [[ZHJNetWorkHelper alloc] init];
        }
    });
    return networkManager;
}

+(void)initialize {
    _sessionManager = [NSURLSession sharedSession];
    
    _requestManager = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:25];
}

#pragma mark 设置请求头
+ (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field {
    [_requestManager setValue:value forHTTPHeaderField:field];//版本
    ZHJLog([LogManager getClassForCoderName:self],@"设置请求头：",_requestManager.allHTTPHeaderFields);
}

#pragma mark 设置超时
+ (void)setRequestTimeoutInterval:(NSTimeInterval)time {
    ZHJLog([LogManager getClassForCoderName:self],@"设置网络超时时间：",[NSString stringWithFormat:@"%f秒",time]);
    if (time !=0 && time !=25) {
        _requestManager.timeoutInterval = time;
    }
}

#pragma mark 状态栏的 菊花开关
+ (void)openNetworkActivityIndicator:(BOOL)open {
    //    [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:open];
}

#pragma mark 隐藏小菊花、loding
-(void)hideAlert {
    [MBManager hideAlert];
    [ZHJNetWorkHelper openNetworkActivityIndicator:NO];
}

#pragma mark 证书校验
- (void)setSecurityPolicy:(ZHJSecurityPolicy *)securityPolicy {
    if (securityPolicy.SSLPinningMode != AFSSLPinningModeNone && ![_requestManager.URL.scheme isEqualToString:@"https"]) {
        NSString *pinningMode = @"Unknown Pinning Mode";
        switch (securityPolicy.SSLPinningMode) {
            case AFSSLPinningModeNone:        pinningMode = @"AFSSLPinningModeNone"; break;
            case AFSSLPinningModeCertificate: pinningMode = @"AFSSLPinningModeCertificate"; break;
            case AFSSLPinningModePublicKey:   pinningMode = @"AFSSLPinningModePublicKey"; break;
        }
        NSString *reason = [NSString stringWithFormat:@"A security policy configured with `%@` can only be applied on a manager with a secure base URL (i.e. https)", pinningMode];
        @throw [NSException exceptionWithName:@"Invalid Security Policy" reason:reason userInfo:nil];
    }
    
    self.securityPolicy = securityPolicy;
//    [super setSecurityPolicy:securityPolicy];
}

- (ZHJSecurityPolicy*)customSecurityPolicy:(NSString*)certificatesName {
    // /先导入证书
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:certificatesName ofType:@".cer"];//证书的路径
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    NSSet *set = [NSSet setWithObjects:certData, nil];
    // 通过指定的验证策略`AFSSLPinningMode` AFSSLPinningModeCertificate 创建证书验证模式
    ZHJSecurityPolicy *securityPolicy = [ZHJSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    // allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO
    // 如果是需要验证自建证书，需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;
    //validatesDomainName 是否需要验证域名，默认为YES；
    //假如证书的域名与你请求的域名不一致，需把该项设置为NO；如设成NO的话，即服务器使用其他可信任机构颁发的证书，也可以建立连接，这个非常危险，建议打开。
    //置为NO，主要用于这种情况：客户端请求的是子域名，而证书上的是另外一个域名。因为SSL证书上的域名是独立的，假如证书上注册的域名是www.google.com，那么mail.google.com是无法验证通过的；当然，有钱可以注册通配符的域名*.google.com，但这个还是比较贵的。
    //如置为NO，建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;
    [securityPolicy setPinnedCertificates:set];
    return securityPolicy;
}

#pragma mark 取消所有请求
+ (void)cancelAllRequest {
    // 锁操作
    @synchronized(self) {
        [[ZHJNetWorkHelper defaultManager].sessionTaskArr enumerateObjectsUsingBlock:^(NSURLSessionTask  *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            [task cancel];
        }];
        [[ZHJNetWorkHelper defaultManager].sessionTaskArr  removeAllObjects];
    }
}

#pragma mark 取消指定请求
+ (void)cancelRequestWithURL:(NSString *)URL {
    if (!URL) { return; }
    @synchronized (self) {
        [[ZHJNetWorkHelper defaultManager].sessionTaskArr  enumerateObjectsUsingBlock:^(NSURLSessionTask  *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task.currentRequest.URL.absoluteString hasPrefix:URL]) {
                [task cancel];
                [[ZHJNetWorkHelper defaultManager].sessionTaskArr  removeObject:task];
                *stop = YES;
            }
        }];
    }
}

#pragma mark 常用网络请求
- (void)sendRequestMethod:(ZHJRequestConfig*)Config
                 progress:(nullable void (^)(NSProgress * _Nullable progress, NSString *tag))progress
                  success:(nullable void(^) (BOOL isSuccess, id _Nullable responseObject))success
                  failure:(nullable void(^) (NSString * _Nullable errorMessage))failure {
    WS(weakSelf);
    [ZHJNetWorkHelper openNetworkActivityIndicator:YES];
    //     设置超时时间
    if (Config.timeoutInterval != 20 ) {
        [ZHJNetWorkHelper setRequestTimeoutInterval:Config.timeoutInterval];
    }
    
    // Loading
    if (Config.hudIsShow) {
        [MBManager showLoading];
    }
    
    // 拼接URL
    NSString *requestPath = Config.url.absoluteString;
    if (![requestPath hasPrefix:@"http"]) {
        return [MBManager showBriefAlert:@"请求地址不存在"];
    } else {
        if (![requestPath containsString:Config.baseUrl]) {
            requestPath = [requestPath substringFromIndex:(Config.url.absoluteString.length - Config.path.length)];
            requestPath = [NSString stringWithFormat:@"%@%@",Config.baseUrl,requestPath];
        }
    }
    _requestManager.URL = [NSURL URLWithString:requestPath];
    
//    [ZHJNetWorkHelper setValue:@"1.0" forHTTPHeaderField:@"ZHJNetWorkHelperVersion"];
    
    // 参数
    __block NSDictionary *parameters = [Config.parameters mutableCopy];
    
    // 是否 缓存
    if (Config.isCache) {
        id parameterDic = [parameters mutableCopy];
        id object = [[ZHJNetCacheManger sharedManager] getCacheDataWithUrl:Config.fullPath];
        if (object) {
            ZHJLog([LogManager getClassForCoderName:self],@"读取缓存 成功");
            [[ZHJNetWorkHelper defaultManager] hideAlert];
            success(YES,object);
            [weakSelf printParamSeting:parameterDic task:nil response:object];
        } else {
            ZHJLog([LogManager getClassForCoderName:self],@"读取缓存 失败");
            weakSelf.isCache = YES;
            Config.isCache = NO;
            [[ZHJNetWorkHelper defaultManager] sendRequestMethod:Config progress:progress success:success failure:failure];
        }
    } else {
        // https SSL验证
        if (Config.certificatesName.length>0) {
            [self setSecurityPolicy:[self customSecurityPolicy:Config.certificatesName]];
        }
        NSURLSessionDataTask * httpDataTask = nil;
        switch (Config.methodType) {
            case RequestMethod_Get:
            {
                _requestManager.HTTPMethod = @"GET";
                
                NSMutableString *mutableUrl = [[NSMutableString alloc] initWithString:requestPath];
                if ([parameters allKeys]) {
                    [mutableUrl appendString:@"?"];
                    for (id key in parameters) {
                        NSString *value = [[parameters objectForKey:key] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
                        [mutableUrl appendString:[NSString stringWithFormat:@"%@=%@&", key, value]];
                    }
                }
                NSString *urlEnCode = [[mutableUrl substringToIndex:mutableUrl.length] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
                _requestManager.URL = [NSURL URLWithString:urlEnCode];
                
                httpDataTask = [_sessionManager dataTaskWithRequest:_requestManager completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[ZHJNetWorkHelper defaultManager] hideAlert];
                        if (error) {
                            failure?failure([weakSelf failHandleWithErrorResponse:error ParamSeting:parameters task:nil]):nil;
                        } else {
                            NSError *error = nil;
                            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                            [weakSelf printParamSeting:parameters task:nil response:dic];
                            if (!error) {
                                success(YES,dic);
                            } else {
                                failure(error.debugDescription);
                            }
                        }
                    });
                }];
            }
                break;
                
            case RequestMethod_Post:
            {
                _requestManager.HTTPMethod = @"POST";
                
                // HTTPbody
                NSString *postStr = [LogManager convertToJsonData:parameters];
                _requestManager.HTTPBody = [postStr dataUsingEncoding:NSUTF8StringEncoding];
                httpDataTask = [_sessionManager dataTaskWithRequest:_requestManager completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[ZHJNetWorkHelper defaultManager] hideAlert];
                        if (error) { //请求失败
                            failure?failure([weakSelf failHandleWithErrorResponse:error ParamSeting:parameters task:nil]):nil;
                        } else {  //请求成功
                            NSError *error = nil;
                            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                            [weakSelf printParamSeting:parameters task:nil response:dic];
                            if (!error) {
                                success(YES,dic);
                            } else {
                                failure(error.description);
                            }
                        }
                    });
                }];
            }
                break;
                
            case RequestMethod_Put:
            {
                _requestManager.HTTPMethod = @"PUT";
                
                // HTTPbody
                NSString *postStr = [LogManager convertToJsonData:parameters];
                _requestManager.HTTPBody = [postStr dataUsingEncoding:NSUTF8StringEncoding];
                httpDataTask = [_sessionManager dataTaskWithRequest:_requestManager completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[ZHJNetWorkHelper defaultManager] hideAlert];
                        if (error) { //请求失败
                            failure?failure([weakSelf failHandleWithErrorResponse:error ParamSeting:parameters task:nil]):nil;
                        } else {  //请求成功
                            NSError *error = nil;
                            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                            [weakSelf printParamSeting:parameters task:nil response:dic];
                            if (!error) {
                                success(YES,dic);
                            } else {
                                failure(error.description);
                            }
                        }
                    });
                }];
            }
                break;
                
            case RequestMethod_Patch:
            {
                _requestManager.HTTPMethod = @"PATCH";
                
                // HTTPbody
                NSString *postStr = [LogManager convertToJsonData:parameters];
                _requestManager.HTTPBody = [postStr dataUsingEncoding:NSUTF8StringEncoding];
                httpDataTask = [_sessionManager dataTaskWithRequest:_requestManager completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[ZHJNetWorkHelper defaultManager] hideAlert];
                        if (error) { //请求失败
                            failure?failure([weakSelf failHandleWithErrorResponse:error ParamSeting:parameters task:nil]):nil;
                        } else {  //请求成功
                            NSError *error = nil;
                            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                            [weakSelf printParamSeting:parameters task:nil response:dic];
                            if (!error) {
                                success(YES,dic);
                            } else {
                                failure(error.description);
                            }
                        }
                    });
                }];
            }
                break;
                
            case RequestMethod_Delete:
            {
                _requestManager.HTTPMethod = @"DELETE";
                
                // HTTPbody
                NSString *postStr = [LogManager convertToJsonData:parameters];
                _requestManager.HTTPBody = [postStr dataUsingEncoding:NSUTF8StringEncoding];
                httpDataTask = [_sessionManager dataTaskWithRequest:_requestManager completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[ZHJNetWorkHelper defaultManager] hideAlert];
                        if (error) { //请求失败
                            failure?failure([weakSelf failHandleWithErrorResponse:error ParamSeting:parameters task:nil]):nil;
                        } else {  //请求成功
                            NSError *error = nil;
                            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                            [weakSelf printParamSeting:parameters task:nil response:dic];
                            if (!error) {
                                success(YES,dic);
                            } else {
                                failure(error.description);
                            }
                        }
                    });
                }];
            }
                break;
        }
        // 添加sessionTask到数组
        httpDataTask ? [[ZHJNetWorkHelper defaultManager].sessionTaskArr addObject:httpDataTask] : nil ;
        [httpDataTask resume];
    }
}

#pragma mark -- 表单上传
+ (void)postMultipartFormWithUrlString:(NSString *)kDetectUrl parameters:(id)parameters data:(NSData*)fileData success:(nullable void(^) (id _Nullable responseObject))successBlock failure:(nullable void(^) (NSString * _Nullable errorMessage))failureBlock {
    
    // 以流的方式上传，大小理论上不受限制，但应注意时间
    // 1、创建URL资源地址
    NSURL *url = [NSURL URLWithString:kDetectUrl];
    // 2、创建Reuest请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 3、配置Request
    //设置Body值方法二，这种方法比较原始，不常用，不过可以用来上传参数和文件
    NSString *BOUNDARY = @"whoislcj";//表单分界线 可以自定义任意值
    [request setValue:[@"multipart/form-data; boundary=" stringByAppendingString:BOUNDARY] forHTTPHeaderField:@"Content-Type"];
    // 文件上传使用post
    [request setHTTPMethod:@"POST"];
    // 设置请求超时
    [request setTimeoutInterval:30.0f];
    //用于存放二进制数据流
    NSMutableData *body = [NSMutableData data];
    
    //追加一个普通表单参数 name=yanzhenjie
    NSString *nameParam = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",BOUNDARY,@"api_id",[parameters objectForKey:@"api_id"],nil];
    [body appendData:[nameParam dataUsingEncoding:NSUTF8StringEncoding]];
    
    //追加一个普通表单参数 pwd=123
    NSString *pwdParam = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",BOUNDARY,@"api_secret",[parameters objectForKey:@"api_secret"],nil];
    [body appendData:[pwdParam dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *userNameParam = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",BOUNDARY,@"name",[parameters objectForKey:@"name"],nil];
    [body appendData:[userNameParam dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *numberParam = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",BOUNDARY,@"id_number",[parameters objectForKey:@"id_number"],nil];
    [body appendData:[numberParam dataUsingEncoding:NSUTF8StringEncoding]];
    
    //追加一个文件表单参数
    // Content-Disposition: form-data; name="<服务器端需要知道的名字>"; filename="<服务器端这个传上来的文件名>"
    // Content-Type: application/octet-stream --根据不同的文件类型选择不同的值
    NSString *file = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\";filename=\"%@\"\r\nContent-Type: Content-Type=image/png\r\n\r\n",BOUNDARY,@"liveness_data_file",@"zhjdem11.png",nil];
    [body appendData:[file dataUsingEncoding:NSUTF8StringEncoding]];
    //追加文件二进制数据
    [body appendData:fileData];
    [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //结束分割线
    NSString *endString = [NSString stringWithFormat:@"--%@--",BOUNDARY];
    [body appendData:[endString dataUsingEncoding:NSUTF8StringEncoding]];
    
    WS(weakSelf);
    // 创建会话
    NSURLSession *session = [NSURLSession sharedSession];
    // 3.开始上传   request的body data将被忽略，而由fromData提供
    NSURLSessionUploadTask *uploadTask= [session uploadTaskWithRequest:request fromData:body completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                ZHJLog([LogManager getClassForCoderName:weakSelf],@"表单上传失败",@"URL",kDetectUrl,error);
                failureBlock(error.description);
            } else {
                NSError *error = nil;
                NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
                if (!error) {
                    //                    NSLog(@"upload success：%@", dic);
                    successBlock(dic);
                } else {
                    failureBlock(error.description);
                }
            }
        });
    }];
    //执行任务
    [uploadTask resume];
}

#pragma mark -- 下载文件
+ (NSURLSessionTask *)downloadWithURL:(NSString *)URL
                              fileDir:(NSString *)fileDir
                             progress:(HttpProgress)progress
                              success:(void(^)(NSString *))success
                              failure:(nullable void(^) (NSString  *_Nullable error))failure {
    _requestManager.URL = [NSURL URLWithString:URL];
    NSURLSessionDownloadTask *downloadTask = [_sessionManager downloadTaskWithRequest:_requestManager completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //  拼接缓存目录
        NSString *downloadDir = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileDir ? fileDir : @"Download"];
        //  打开文件管理器
        NSFileManager *fileManager = [NSFileManager defaultManager];
        //  创建Download目录
        [fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:nil];
        //  拼接文件路径
        NSString *filePath = [downloadDir stringByAppendingPathComponent:response.suggestedFilename];
        NSLog(@"downloadDir = %@",downloadDir);
        //  返回文件位置的URL路径
        //        return [NSURL fileURLWithPath:filePath];
        if(failure && error) {failure(error.description) ; return ;};
        success ? success(filePath /** NSURL->NSString*/) : nil;
        
    }];
    //开始下载
    [downloadTask resume];
    downloadTask ? [[ZHJNetWorkHelper defaultManager].sessionTaskArr addObject:downloadTask] : nil ;
    return downloadTask;
}

#pragma mark 请求参数打印
-(void)printParamSeting:(NSDictionary*)dic task:( NSURLSessionDataTask * _Nullable )task response:(id)responseObject {
    if (dic||task) {
        if (task) {
            NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
            if (response) {
                dic = @{@"URL":response.URL.absoluteString,@"header":response.allHeaderFields};
            }
            if (dic) {
                dic = @{@"URL":response.URL.absoluteString,@"header":response.allHeaderFields,@"param":dic};
            }
        }
        ZHJLog([LogManager getClassForCoderName:self],@"请求头：\n",[LogManager convertToJsonData:dic]);
    }
    
    if (responseObject) {
        ZHJLog([LogManager getClassForCoderName:self],@"请求完成response：\n",[LogManager convertToJsonData:responseObject]);
    }
}

#pragma mark 报错信息
/**
 处理报错信息
 
 @param error AFN返回的错误信息
 @param task 任务
 @return description
 */
- (NSString *)failHandleWithErrorResponse:( NSError * _Nullable )error ParamSeting:(NSDictionary*)dic task:( NSURLSessionDataTask * _Nullable )task {
    __block NSString *message = nil;
    // 打印请求 参数
    [self printParamSeting:dic task:task response:nil];
    // 这里可以直接设定错误反馈，也可以利用AFN 的error信息直接解析展示
    NSData *afNetworking_errorMsg = [error.userInfo objectForKey:ZHJNetworkingOperationFailingURLResponseDataErrorKey];
    ZHJLog([LogManager getClassForCoderName:self],@"afNetworking_错误信息:/n",[[NSString alloc]initWithData:afNetworking_errorMsg encoding:NSUTF8StringEncoding]);
    if (!afNetworking_errorMsg) {
        message = @"网络连接失败";
    }
    NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
    NSInteger responseStatue = response.statusCode;
    if (responseStatue >= 500) {  // 网络错误
        message = @"服务器维护升级中,请耐心等待";
    } else if (responseStatue >= 400) {
        if (afNetworking_errorMsg) {
            // 错误信息
            NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:afNetworking_errorMsg options:NSJSONReadingAllowFragments error:nil];
            message = responseObject[@"error"];
        }
    }
    ZHJLog([LogManager getClassForCoderName:self],@"错误信息",message);
    NSLog(@"错误信息：\n %@",message);
    return message;
}

#pragma mark - NSURLSessionDelegate

- (void)URLSession:(NSURLSession *)session
didBecomeInvalidWithError:(NSError *)error
{
//    if (self.sessionDidBecomeInvalid) {
//        self.sessionDidBecomeInvalid(session, error);
//    }
//
//    [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDidInvalidateNotification object:session];
}

- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
    __block NSURLCredential *credential = nil;
    
//    if (self.sessionDidReceiveAuthenticationChallenge) {
//        disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
//    } else {
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
                credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                if (credential) {
                    disposition = NSURLSessionAuthChallengeUseCredential;
                } else {
                    disposition = NSURLSessionAuthChallengePerformDefaultHandling;
                }
            } else {
                disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
            }
        } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
//    }
    
    if (completionHandler) {
        completionHandler(disposition, credential);
    }
}

#pragma mark - NSURLSessionTaskDelegate

- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
        newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest *))completionHandler
{
    NSURLRequest *redirectRequest = request;
    
//    if (self.taskWillPerformHTTPRedirection) {
//        redirectRequest = self.taskWillPerformHTTPRedirection(session, task, response, request);
//    }
    
    if (completionHandler) {
        completionHandler(redirectRequest);
    }
}

- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
    __block NSURLCredential *credential = nil;
    
//    if (self.taskDidReceiveAuthenticationChallenge) {
//        disposition = self.taskDidReceiveAuthenticationChallenge(session, task, challenge, &credential);
//    } else {
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
                disposition = NSURLSessionAuthChallengeUseCredential;
                credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            } else {
                disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
            }
        } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
//    }
    
    if (completionHandler) {
        completionHandler(disposition, credential);
    }
}





@end

